#ifndef CheapText_First
#define CheapText_First
#ifdef __GNUG__
#pragma interface
#endif

#include "Text.h"

class RegularExp;
class CheapTextIter;

//---- CheapText ---------------------------------------------------------------

class CheapText: public Text {
public:
	MetaDef(CheapText);
	CheapText(int cap= cTextInitCap, Font *f= gSysFont);
	CheapText(const byte *s, int l= -1, Font *f= gSysFont);
	CheapText(const char *s, int l= -1, Font *f= gSysFont);
	~CheapText();
	void Init(int cap, Font *f= gSysFont, const byte *s= 0, int l= -1);

	//---- editing
	void CopyInStr(byte *s, int strSize, int from, int to);
	void AddChar(int at, byte b);

	//---- accessing
	const char *AsString();
	byte &operator[](int i);
	int Size();
	int Search(RegularExp *rex, int *nMatched, int start= 0,
				int range= cMaxInt, bool dir= cSearchForward);

	//---- iterators
	TextIter *MakeIterator(int from= 0, int to= cMaxInt, void *placement= 0);

	//---- TextPainter contract
	byte *GetLineAccess(byte **buf, int from, int to);

	//---- input/output
	OStream &PrintOn(OStream&);
	IStream &ReadFrom(IStream&);
	OStream &PrintOnAsPureText(OStream &s);
	IStream &ReadFromAsPureText(IStream&, long sizeHint= -1);

protected:
	void InitNew();
	void Terminate();
	void InsertBytes(byte *s, int l, int from, int to);
	void ReplaceRange(int from, int to, Text *src, int sfrom, int sto);
	Text *MakeScratchText(byte *buf, int l);

	byte CharAt(int i);

private:
	void Expand(int);
	bool HighWaterMark(int n);
	bool LowWaterMark();

private:
friend CheapTextIter;
	int size;       // next free slot
	int capacity;   // size of allocated memory
	byte *cont;
};

inline bool CheapText::HighWaterMark(int n)
	{ return (bool) (cont == NULL || size+n >= capacity); }

inline bool CheapText::LowWaterMark()
	{ return (bool) (size < capacity/5); }

inline byte CheapText::CharAt(int i)
	{ return cont[i]; }

//---- CheapTextIter -----------------------------------------------------------

class CheapTextIter: public TextIter {
	Font *font;
public:
	CheapTextIter(Text *s, int from= 0, int to= cMaxInt);
	int operator()(int *width= 0, LineDesc* l= 0);
		// returns width of the character too
	int Token(int *width, LineDesc* l= 0);
		// returns next token and its size
};

#endif
